﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml;
using HtmlAgilityPack;
using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace Nwsfeed
{    
    public class RSSFeed : INotifyPropertyChanged
    {
        private String title;
        private String summary;
        private String uri;
        private String homepageUri;
        private String encoding;
        private String imageUri;
        private String imageCacheUri;
		private bool isChecked;
        private ObservableCollection<FeedItem> posts;
        private bool isLoading;

        public String HomepageUri { get; set; }
        public String Title { get { return title; } set { title = value; NotifyPropertyChanged("Title"); } }
        public String Summary { get { return summary; } set { summary = value; NotifyPropertyChanged("Summary"); } }
        public String Uri { get { return uri; } set { uri = value; NotifyPropertyChanged("Uri"); } }
        public String Encoding { get { return encoding; } set { encoding = value; NotifyPropertyChanged("Encoding"); } }
        public String ImageCacheUri { get { return imageCacheUri; } 
            set { imageCacheUri = value; NotifyPropertyChanged("ImageCacheUri"); } }

		public bool IsChecked { get { return isChecked; } set { isChecked = value; NotifyPropertyChanged("IsChecked"); } }
        public bool IsLoading { get { return isLoading; } set { isLoading = value; NotifyPropertyChanged("IsLoading"); } }
        public ObservableCollection<FeedItem> Posts { get { return posts; } }

        public bool FetchedSuccessfully { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public RSSFeed()
        {
            IsLoading = true;
            posts = new ObservableCollection<FeedItem>();
        }

        public RSSFeed(String uri)
        {
            IsLoading = true;
            posts = new ObservableCollection<FeedItem>();
            Uri = uri;
            //Fetch();
        }

        public void Fetch()
        {
            IsLoading = true;
            if (Uri != "")
            {
                try
                {
                    MyWebClient client = new MyWebClient();

                    try
                    {
                        HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(Uri.ToString());
                        myHttpWebRequest.Timeout = 100;
                        using (HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse())
                        {
                        if (myHttpWebResponse.ContentEncoding != "")
                        {
                            System.Text.Encoding enc = System.Text.Encoding.GetEncoding(myHttpWebResponse.ContentEncoding);
                            client.Encoding = enc;
                        }
                        else
                            client.Encoding = System.Text.Encoding.UTF8;
                        }
                    }
                    catch (Exception ex)
                    {
                        client.Encoding = System.Text.Encoding.UTF8;
                    }

                    String str = client.DownloadString(Uri);

                    str = Regex.Replace(str, "<!--.*?-->", String.Empty, RegexOptions.Singleline);
                    FeedXmlReader reader = new FeedXmlReader();
                    RSSFeed feed = reader.Load(str, new Uri(Uri));

                    if (feed.Title != null)
                        Title = feed.Title;
                    if (feed.Encoding != null)
                        Encoding = feed.Encoding;
                    if (feed.Summary != null)
                        Summary = feed.Summary;
                    if (feed.Posts != null)
                        posts = feed.Posts;

                    if (feed.HomepageUri != null)
                        HomepageUri = feed.HomepageUri;

                    ImageCacheUri = feed.ImageCacheUri;

                    IsLoading = false;
                    FetchedSuccessfully = true;
                }
                catch (Exception e)
                {
                    IsLoading = false;
                    FetchedSuccessfully = false;
                }

            }
        }

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public class FeedItem
    {
        public String Title { get; set; }
        public String Summary { get; set; }
        public String Link { get; set; }
        public double FontSize { get; set; }
        public String DatePublished {get;set;}
        private DateTime pubDate;
        public DateTime PubDate { get { return pubDate; } set { pubDate = value; init(); } }

        public FeedItem(String Title, String Summary, String Link, DateTime PubDate)
        {
            this.Title = Title;
            this.FontSize = 36.0f;
            this.Summary = Summary;
            this.PubDate = PubDate;
            this.Link = Link;
        }

        public FeedItem(String Title, String Summary, String Link, String PubDate)
        {
            this.Title = Title;
            this.Summary = Summary;
            this.FontSize = 36.0f;
            this.DatePublished = PubDate;
            this.Link = Link;
            this.PubDate = DateTime.UtcNow;
        }

        private void init()
        {
            String month = "";
            switch (PubDate.Month)
            {
                case 1:
                    month = "Jan";
                    break;
                case 2:
                    month = "Feb";
                    break;
                case 3:
                    month = "Mar";
                    break;
                case 4:
                    month = "Apr";
                    break;
                case 5:
                    month = "May";
                    break;
                case 6:
                    month = "Jun";
                    break;
                case 7:
                    month = "Jul";
                    break;
                case 8:
                    month = "Aug";
                    break;
                case 9:
                    month = "Sep";
                    break;
                case 10:
                    month = "Oct";
                    break;
                case 11:
                    month = "Nov";
                    break;
                case 12:
                    month = "Dec";
                    break;
            }

            String minute;
            if (pubDate.Minute == 0)
                minute = "00";
            else
                minute = pubDate.Minute.ToString();

            DatePublished = PubDate.Hour + ":" + minute + ", " + PubDate.Day + " " + month;
        }
    }
}
